﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using COFE.Core.Validater;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using COFE.Core.Utils;
using COFE.Core;

namespace COFE.Core
{
    /// <summary>
    /// Represent a property, it's value type and value
    /// </summary>
    public class PropertyPair
    {
        #region Public Properties
        /// <summary>
        /// Property key (e.g. FileSystemProperties.FullName)
        /// </summary>
        public object Property { get; private set; }
        /// <summary>
        /// Type of value.
        /// </summary>
        public Type Type { get; private set; }

        /// <summary>
        /// Value of value.
        /// </summary>
        public object Value { get; private set; }

        public bool HasValue { get { return Value != null; } }

        public Int32 ValueAsInt32 { get { return (Int32)Value; } }
        public Int64 ValueAsInt64 { get { return (Int64)Value; } }
        public UInt64 ValueAsUInt64 { get { return (UInt64)Value; } }
        public string ValueAsString { get { return Value as String; } }
        public bool ValueAsBoolean { get { return (bool)Value; } }
        public DateTime ValueAsUtcDateTime { get { return (DateTime)Value; } }
        public DateTime ValueAsLocalDateTime { get { return ((DateTime)Value).ToLocalTime(); } }

        #endregion

        #region Methods

        public override string ToString()
        {
            return string.Format("{0} = {1}", Property, Value);
        }        

        public Stream ToMemoryStream(out MediaType mediaType)
        {
            MemoryStream ms = new MemoryStream();
            SaveToStream(ms, out mediaType);
            ms.Seek(0, SeekOrigin.Begin);
            return ms;
        }

        public void SaveToStream(Stream stream, out MediaType mediaType)
        {
            mediaType = MediaType.Stream;
            if (Type == typeof(Bitmap))
            {
                (Value as Bitmap).SaveAsPNGStream(stream);
                mediaType = MediaType.Png;
            }
            else
            {
                using (StreamWriter sw = new StreamWriter(stream))
                {
                    sw.Write(Value);
                    sw.Flush();
                }
            }
        }

        #endregion


        public PropertyPair(object property, object value)            
        {
            Property = property;

            //Type dataType = Enum.GetUnderlyingType(property.GetType());
            Type = PropertyTypeExtension.GetDefaultPropertyType(property);

            //Compare value type to declared type in Attribute
            IPropertyValidaterExtension.VerifyValue(property, value);
      
            Value = value;
        }

        protected PropertyPair(object property)
        {
            Property = property;            
            Type = PropertyTypeExtension.GetDefaultPropertyType(property);
            Value = null;
        }

        public override bool Equals(object obj)
        {
            if (obj is PropertyPair)
                return Property.Equals((obj as PropertyPair).Property);
            return false;
        }

        public override int GetHashCode()
        {
            return Property.GetHashCode();
        }

    }
}
